import java.util.ArrayList;
import java.util.HashMap;


public class GenerateurMouvement {
	private int[][] board;
	private HashMap<Character, Integer> aMap;
	private ArrayList<Mouvement> alMvtTotal;
	private int numCoup;
	
	public GenerateurMouvement(int[][] board, int couleurPion,int numCoup) {
		System.out.println("Numcoup "+numCoup);
		aMap = new HashMap<Character, Integer>();
		aMap.put('A' , 0);
		aMap.put('B' , 1);
		aMap.put('C' , 2);
		aMap.put('D' , 3);
		aMap.put('E' , 4);
		aMap.put('F' , 5);
		aMap.put('G' , 6);
		aMap.put('H' , 7);
		
		this.board = board;
		this.numCoup = numCoup;
		alMvtTotal = new ArrayList<Mouvement>();
		 ArrayList<String> alLigneMax = trouverLigneMax(couleurPion);
		for(String s : alLigneMax) {
			System.out.println("MAX: "+s);
		}
		for(int i=0; i< 8; i++) {
			for(int j=0; j<8; j++) {
				//Si on est est sur un de nos pions, on regarde les déplacements qu'il peut faire
				if(board[i][j] == couleurPion) {
					ArrayList<Mouvement> alMvtPart = trouverMouvement(i, j, couleurPion,alLigneMax);
					if(alMvtPart.size() > 0) //Si l'arrayList partielle contient au moins un élément, on l'ajoute
						alMvtTotal.addAll(alMvtPart);
				}
			}
		}
		System.out.println("Total Mvt : "+alMvtTotal.size());
		for(Mouvement mvt : alMvtTotal) {
			System.out.println(mvt.toString());
		}
	}
	
	private ArrayList<String> trouverLigneMax(int couleurPion) {
		ArrayList<String> tab = new ArrayList<String>();
		int max=0;
		for(int i=0; i< 8; i++) {
			for(int j=0; j<8; j++) {
				ArrayList<String> dejaCherche = new ArrayList<String>();
				int res = checkVoisin(i,j, couleurPion,dejaCherche);
				if(res > max) {
					tab.clear();
					tab.add(i+"-"+j+"-"+res);
					max = res;
				} else if(res == max) {
					tab.add(i+"-"+j+"-"+res);
				}
			}
		}
		return tab;
	}
	
	public int checkVoisin(int i , int j, int couleurPion, ArrayList<String> dejaCherche)
	{
		int val=0;
		
		if(i > 7 || i <0 || j > 7 || j < 0) {
			return val;
		}
		if(board[i][j] == couleurPion && !dejaCherche.contains(i+"-"+j)) {
			dejaCherche.add(i+"-"+j);
			val += checkVoisin(i+1,j,couleurPion,dejaCherche);
			val += checkVoisin(i-1,j,couleurPion,dejaCherche);
			val += checkVoisin(i,j+1,couleurPion,dejaCherche);
			val += checkVoisin(i,j-1,couleurPion,dejaCherche);
			
			val += checkVoisin(i-1,j-1,couleurPion,dejaCherche);
			val += checkVoisin(i+1,j-1,couleurPion,dejaCherche);
			val += checkVoisin(i-1,j+1,couleurPion,dejaCherche);
			val += checkVoisin(i+1,j+1,couleurPion,dejaCherche);
			val++;
		}
		return val;
	}
	
	public ArrayList<Mouvement> trouverMouvement(int x, int y, int couleurPion,ArrayList<String> alLigneMax) {
		int couleurAdverse = 2;
		if(couleurPion == 2)
			couleurAdverse = 4;
		
		int nbPionLigne = 0;
		int nbPionColonne = 0;
		int nbPionDiag1 = 0; //Pars de la case la plus en haut à gauche vers celle en bas à droite -> \
		int nbPionDiag2 = 0; //Pars de la case la plus en haut à droite vers celle en bas à gauche -> /
		
		//Compte le nombre de pion sur la ligne
		for(int j=0; j<8; j++) {
			if(board[x][j] != 0) nbPionLigne++;
		}
		
		//Compte le nombre de pion sur la colonne
		for(int i=0; i<8; i++) {
			if(board[i][y] != 0) nbPionColonne++;
		}
		
		//Compte le nombre de pion sur la diagonale 1 \
		for(int i=x, j=y; i<8 && j<8; i++, j++ ) {
			if(board[i][j] != 0) nbPionDiag1++;
		}
		for(int i=x-1, j=y-1; i>=0 && j>=0; i--, j-- ) {
			if(board[i][j] != 0) nbPionDiag1++;
		}
		
		//Compte le nombre de pion sur la diagonale 2 /
		for(int i=x, j=y; i>=0 && j<8; i--, j++ ) {
			if(board[i][j] != 0) nbPionDiag2++;
		}
		for(int i=x+1, j=y-1; i<8 && j>=0; i++, j--) {
				if(board[i][j] != 0) nbPionDiag2++;
		}
		
		
	//	System.out.println(x+"-"+y+" => "+nbPionLigne+"/"+nbPionColonne+"/"+nbPionDiag1+"/"+nbPionDiag2);
		
		ArrayList<Mouvement> alMvt = new ArrayList<Mouvement>();
		
		//Déplacement sur la ligne, on verifie qu'on ne dépasse pas du plateau
		int nbPionAdverse = 0;
		if(y+nbPionLigne < 8 && board[x][y+nbPionLigne] != couleurPion) {
			for(int j=y+1; j <= y+nbPionLigne-1; j++)
				if(board[x][j] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) > y) {
						if(Math.abs(y-Integer.parseInt(tmp[1])) > poidsTmp) {
							poidsTmp = Math.abs(y-Integer.parseInt(tmp[1]));
						}
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				alMvt.add(new Mouvement(x+"-"+y, x+"-"+(y+nbPionLigne),poidsTmp));
			}
		}
		
		nbPionAdverse = 0;
		if(y-nbPionLigne >= 0 && board[x][y-nbPionLigne] != couleurPion) {
			for(int j=y-1; j >= y-nbPionLigne+1; j--)
				if(board[x][j] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) < y) {
						if(Math.abs(y-Integer.parseInt(tmp[1])) > poidsTmp) {
							poidsTmp = Math.abs(y-Integer.parseInt(tmp[1]));
						}
						
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				alMvt.add(new Mouvement(x+"-"+y, x+"-"+(y-nbPionLigne),poidsTmp));
			}
		}
		
		//Déplacement sur la colonne, on verifie qu'on ne dépasse pas du plateau
		nbPionAdverse = 0;
		if(x+nbPionColonne < 8 && board[x+nbPionColonne][y] != couleurPion) {
			for(int i=x+1; i <= x+nbPionColonne-1; i++)
				if(board[i][y] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) > x && Integer.parseInt(tmp[1]) == y) {
						if(Math.abs(x-Integer.parseInt(tmp[1])) > poidsTmp) {
							poidsTmp = Math.abs(x-Integer.parseInt(tmp[0]));
						}
						
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				alMvt.add(new Mouvement(x+"-"+y, (x+nbPionColonne)+"-"+y,poidsTmp));
			}
		}
		
		nbPionAdverse = 0;
		if(x-nbPionColonne >= 0 && board[x-nbPionColonne][y] != couleurPion) {
			for(int i=x-1; i >= x-nbPionColonne+1; i--)
				if(board[i][y] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) < x && Integer.parseInt(tmp[1]) == y) {
						if(Math.abs(x-Integer.parseInt(tmp[1])) > poidsTmp) {
							poidsTmp = Math.abs(x-Integer.parseInt(tmp[0]));
						}
						
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				
				alMvt.add(new Mouvement(x+"-"+y, (x-nbPionColonne)+"-"+y,poidsTmp));
			}
		}
		
		//Déplacement sur la diagonale1 \, on verifie qu'on ne dépasse pas du plateau
		nbPionAdverse = 0;
		if(x+nbPionDiag1 < 8 && y+nbPionDiag1 < 8 && board[x+nbPionDiag1][y+nbPionDiag1] != couleurPion) {
			for(int i=x+1, j=y+1; i <= x+nbPionDiag1-1 && j <= y+nbPionDiag1-1; i++,j++)
				if(board[i][j] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) > x && Integer.parseInt(tmp[1]) > y) {
						if(Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0])) > poidsTmp) {
							poidsTmp = Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0]));
						}
						
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				
				
				alMvt.add(new Mouvement(x+"-"+y, (x+nbPionDiag1)+"-"+(y+nbPionDiag1),poidsTmp));
			}
		}
		
		nbPionAdverse = 0;
		if(x-nbPionDiag1 >= 0 && y-nbPionDiag1 >= 0 && board[x-nbPionDiag1][y-nbPionDiag1] != couleurPion) {
			for(int i=x-1, j=y-1; i >= x-nbPionDiag1+1 && j >= y-nbPionDiag1+1; i--,j--)
				if(board[i][j] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) < x && Integer.parseInt(tmp[1]) < y) {
						if(Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0])) > poidsTmp) {
							poidsTmp = Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0]));
						}
						
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				
				alMvt.add(new Mouvement(x+"-"+y, (x-nbPionDiag1)+"-"+(y-nbPionDiag1),poidsTmp));
			}
		}
		
		//Déplacement sur la diagonale2 /, on verifie qu'on ne dépasse pas du plateau
		nbPionAdverse = 0;
		if(x-nbPionDiag2 >= 0 && y+nbPionDiag2 < 8 && board[x-nbPionDiag2][y+nbPionDiag2] != couleurPion) {
			for(int i=x-1, j=y+1; i >= x-nbPionDiag2+1 && j <= y+nbPionDiag2-1; i--,j++)
				if(board[i][j] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) < x && Integer.parseInt(tmp[1]) > y) {
						if(Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0])) > poidsTmp) {
							poidsTmp = Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0]));
						}
						
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				
				alMvt.add(new Mouvement(x+"-"+y, (x-nbPionDiag2)+"-"+(y+nbPionDiag2),poidsTmp));
			}
		}
		
		nbPionAdverse = 0;
		if(x+nbPionDiag2 < 8 && y-nbPionDiag2 >= 0 && board[x+nbPionDiag2][y-nbPionDiag2] != couleurPion) {
			for(int i=x+1, j=y-1; i <= x+nbPionDiag2-1 && j >= y-nbPionDiag2+1; i++,j--)
				if(board[i][j] == couleurAdverse) nbPionAdverse++;
			
			if(nbPionAdverse == 0) //On s'arrête AVANT la derniere case. Il ne doit pas y avoir de pions adverse sur le chemin (mais il peut y en avoir un à l'arrivée)
			{
				int poidsTmp = -1000;
				for(String s: alLigneMax) {
					String[] tmp = s.split("-");
					if(Integer.parseInt(tmp[0]) > x && Integer.parseInt(tmp[1]) < y) {
						if(Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0])) > poidsTmp) {
							poidsTmp = Math.abs(y-Integer.parseInt(tmp[1]))+Math.abs(x-Integer.parseInt(tmp[0]));
						}
						
					}
					//si le pion est dans la ligne max, on ne le joue que si on a pas le choix
					if(Integer.parseInt(tmp[0]) == x && Integer.parseInt(tmp[1]) == y) {
						poidsTmp=-2000;
						break;
					}
				}
				
				
				System.out.println(x+" "+y+" "+poidsTmp);
				
				alMvt.add(new Mouvement(x+"-"+y, (x+nbPionDiag2)+"-"+(y-nbPionDiag2),poidsTmp));
			}
		}
		
		return alMvt;
	}
	
	public String getMvtApresElagage() {
		int poidsMin = -2001;
	    String deplacement=""; 
	    int poidsr = -1;
		for(Mouvement m : alMvtTotal) {
			System.out.println("Poids: "+m.getPoids());
			if(m.getPoids() > poidsMin) {
				poidsMin = m.getPoids();
				deplacement = m.getDeplacement();
				poidsr=m.getPoids();
			}
		}
		System.out.println("PPPPPPPOOOOOOOOOOOOIDS "+poidsr+" "+deplacement);
		return deplacement;
	}
}
